//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.base.app_core.util.security;

import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Random;
import java.util.StringTokenizer;

public class RSA {
    private BigInteger primes;
    private BigInteger n;
    private BigInteger ran;
    private BigInteger d;
    private BigInteger e;
    private String m;
    Random rnd;
    private int numBit;

    public RSA() {
        this.primes = BigInteger.ZERO;
        this.d = BigInteger.ZERO;
        this.e = BigInteger.ZERO;
        this.rnd = new Random();
        this.numBit = 512;
    }

    public BigInteger getPrimes(Random rnd) {
        return this.primes = BigInteger.probablePrime(this.numBit, rnd);
    }

    public BigInteger getN(BigInteger p, BigInteger q) {
        return this.n = p.multiply(q);
    }

    public BigInteger getRan(BigInteger p, BigInteger q) {
        this.ran = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
        return this.ran;
    }

    public BigInteger getE(BigInteger ran) {
        BigInteger temp = null;
        this.e = BigInteger.ZERO;

        do {
            temp = BigInteger.probablePrime(this.numBit, this.rnd);
            if (temp.gcd(ran).equals(BigInteger.ONE)) {
                this.e = temp;
            }
        } while(!temp.gcd(ran).equals(BigInteger.ONE));

        return this.e;
    }

    public BigInteger getKey(BigInteger e, BigInteger ran) {
        this.d = e.modInverse(ran);
        return this.d;
    }

    public static BigInteger[] encodeRSA(byte[][] em, BigInteger e, BigInteger n) {
        BigInteger[] encodeM = new BigInteger[em.length];

        for(int i = 0; i < em.length; ++i) {
            encodeM[i] = new BigInteger(em[i]);
            encodeM[i] = encodeM[i].modPow(e, n);
        }

        return encodeM;
    }

    public static byte[][] dencodeRSA(BigInteger[] encodeM, BigInteger d, BigInteger n) {
        if (encodeM == null) {
            return null;
        } else {
            byte[][] dencodeM = new byte[encodeM.length][];
            int lung = encodeM.length;

            for(int i = 0; i < lung; ++i) {
                dencodeM[i] = encodeM[i].modPow(d, n).toByteArray();
            }

            return dencodeM;
        }
    }

    public static byte[][] byteToEm(byte[] arrayByte, int numBytes) {
        int dab = (arrayByte.length - 1) / numBytes + 1;
        int iab = 0;
        byte[][] arrayEm = new byte[dab][];

        int i;
        int j;
        for(i = 0; i < dab - 1; ++i) {
            arrayEm[i] = new byte[numBytes];

            for(j = 0; j < numBytes; ++iab) {
                arrayEm[i][j] = arrayByte[iab];
                ++j;
            }
        }

        i = dab - 1;
        arrayEm[i] = new byte[arrayByte.length - iab];

        for(j = 0; j < arrayEm[i].length; ++iab) {
            arrayEm[i][j] = arrayByte[iab];
            ++j;
        }

        return arrayEm;
    }

    public static byte[] StringToByte(byte[][] arraySenS) {
        if (arraySenS == null) {
            return null;
        } else {
            int dab = 0;

            int i;
            for(i = 0; i < arraySenS.length; ++i) {
                if (arraySenS[i] == null) {
                    return null;
                }

                dab += arraySenS[i].length;
            }

            int iab = 0;
            byte[] arrayByte = new byte[dab];

            for(i = 0; i < arraySenS.length; ++i) {
                for(int j = 0; j < arraySenS[i].length; ++iab) {
                    arrayByte[iab] = arraySenS[i][j];
                    ++j;
                }
            }

            return arrayByte;
        }
    }

    public static String enCode(String em, BigInteger e, BigInteger n) throws Exception {
        em = URLEncoder.encode(em, "UTF-8");
        byte[] arraySendM = em.getBytes();
        int numeroByte = 63;
        byte[][] encodSendM = byteToEm(arraySendM, numeroByte);
        BigInteger[] encodingM = encodeRSA(encodSendM, e, n);
        StringBuffer encondSm = new StringBuffer();

        for(int i = 0; i < encodingM.length; ++i) {
            encondSm.append(encodingM[i].toString());
            encondSm.append("  ");
        }

        return encondSm.toString();
    }

    public static String deCode(String encondM, BigInteger d, BigInteger n) throws Exception {
        StringTokenizer StringEncM = new StringTokenizer(encondM, " ", false);
        int numeroToken = StringEncM.countTokens();
        BigInteger[] StringToByte = new BigInteger[numeroToken];

        for(int i = 0; i < numeroToken; ++i) {
            StringToByte[i] = new BigInteger(StringEncM.nextToken());
        }

        byte[][] encodeM = dencodeRSA(StringToByte, d, n);
        byte[] sendMessage = StringToByte(encodeM);
        String message = new String(sendMessage);
        message = URLDecoder.decode(message, "UTF-8");
        return message;
    }

    public static void main(String[] args) throws Exception {
        BigInteger e = new BigInteger("10030123539446421279035559581668070616148901584561745989261348864214076624150096041660120102260309817204518950616998301393228862650046769070770209198526901");
        BigInteger n = new BigInteger("110331107161847987585239244516642343476414931580042600603311339373335515419916990952386873237326112470500040843898389090004526569833260021057512675499081830783424709187439513025681589364470457788313283974218113183949165773688933719281352800243488472412019923466042938029341530955211848209832740210585438313017");
        BigInteger d = new BigInteger("77413634529210721602008284339323216115774740568069489613626644782937410283866155342202837334028870239309992564681602809765372414855433931106127939211572206899592353000991229856982425826181207364762275509041749014510496981401537496164136033524297432282421719166710087814999213803857235316225040242734808694761");
        String encondM = enCode("{\"phone\":\"13888888888\"}", e, n);
        System.out.println("明文加密：" + encondM);
        System.out.println("密文解密：" + deCode(encondM, d, n));
    }
}
